#include "WebSocketData.hpp"


bool WebSocketData::peekBuffer(Buffer* buffer) {
    if (buffer->readableSize() < 2) return false;
    const char* maskAndLenPos = buffer->getReadPos() + 1;
    bool mask = (*maskAndLenPos) & 0x80 != 0;
    uint8_t len1 = (*maskAndLenPos) & 0x7F;
    uint64_t shouldLen = 2;

    if (mask) shouldLen += 4;

    if (len1 == 126) {
        shouldLen +=2;
        if (buffer->readableSize() < shouldLen) return false;
        uint16_t len2 = ntohs((*(uint16_t*)(maskAndLenPos+1)));
        shouldLen += len2;
        if (buffer->readableSize() < shouldLen) return false;
        
    }
    else if (len1 == 127) {
        shouldLen += 8;
        if (buffer->readableSize() < 10) return false;
        uint32_t biglen = ntohl(*((uint32_t*)(maskAndLenPos+1)));
        uint32_t biglen2 = ntohl(*((uint32_t*)(maskAndLenPos+1)));
        uint64_t len2 = (((uint64_t)biglen << 32) + biglen2);
        std::cout << "！！！大于16位能表示的数据，转换后：" << ((int)len2) << std::endl;
        shouldLen += len2;
        if (buffer->readableSize() < shouldLen) return false;
    }
    else {
        shouldLen += len1;
        if (buffer->readableSize() < shouldLen) return false;
    }
    
    return true;


}


void WebSocketData::readFromBuffer(Buffer* buffer) {
    auto temp = buffer->getData<std::vector<char>>(1);
    head_ = temp[0];
    char optcode = head_ & 0x0f;
    // std::cout << "optcode:" << (int)optcode << std::endl;

    temp = buffer->getData<std::vector<char>>(1);
    char maskedAndLen_ = temp[0];

    masked_ = (maskedAndLen_ & 0x80) != 0;
    len_ = static_cast<size_t>(maskedAndLen_ & 0x7f);

    if (len_ == 126) {
        temp = buffer->getData<std::vector<char>>(2);
        len_ = static_cast<size_t>(ntohs(*((uint16_t*)temp.data())));
    }
    else if (len_ == 127) {
        temp = buffer->getData<std::vector<char>>(2);
        uint32_t biglen = ntohl(*((uint32_t*)(temp.data())));
        uint32_t biglen2 = ntohl(*((uint32_t*)(temp.data()+4)));
        len_ = static_cast<size_t>((((uint64_t)biglen << 32) + biglen2));
    }

    if (masked_) {
        maskingkey_ = buffer -> getData<std::vector<char>>(4);
    }


    payload_ = buffer->getData<std::string>(len_);


    if (masked_) {
        for (size_t i = 0; i!=payload_.size(); ++i) {
            payload_[i] ^= maskingkey_[i%4];
        }
    }

}


void WebSocketData::setPayLoad(const std::string& payload) {
    head_ = 0x81;
    masked_ = false;
    len_ = payload.size();
    maskingkey_ = {};
    payload_ = payload;
}



void WebSocketData::writeToBuffer(Buffer* buffer) {
    buffer->appendString(&head_, 1);
    char maskedAndLen;
    maskedAndLen = 0x00;

    if (len_ <= 125) {
        maskedAndLen |= (uint8_t)len_;
        buffer->appendString(&maskedAndLen, 1);
    }
    else {// 大于125有bug
        maskedAndLen |= (uint8_t)126;
        buffer->appendString(&maskedAndLen, 1);
        uint16_t templen = htons(len_);
        buffer->appendString((char*)&templen, 2);
    }

    buffer->appendString(payload_.c_str(), payload_.size());
}